#include "MyList.h"
// #include <cstddef>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static MyNode *mo_node_new(MyList *tl,void *cum){
    MyNode *tmp = malloc(sizeof(MyNode));
    tmp->value = malloc(tl->size);
    if(cum==NULL){
        tmp->value=NULL;
        tmp->next=NULL;
        return tmp;
    }
    memcpy(tmp->value, cum, tl->size);
    tmp->next=NULL;
    return tmp;
}

MyList *mo_mylist_new(int size){
    MyList *tmp = malloc(sizeof(MyList));
    tmp->size=size;
    tmp->head=mo_node_new(tmp, NULL);
    return tmp;
}

mo_list_iter mo_mylist_start(MyList *tl){
    mo_list_iter tmp = {tl->head->next,tl->size};
    return tmp;
}

void mo_mylist_iter_next(mo_list_iter *iter){
    (*iter).var = (iter->var->next);
}

void mo_get_iter_var(void *getter, mo_list_iter iter){
    memcpy(getter, iter.var->value, iter.size);
}

void mo_mylist_add_head(MyList *tl, void *cum){
    MyNode *tmp=tl->head->next;
    tl->head->next=mo_node_new(tl, cum);
    tl->head->next->next=tmp;
}

void mo_mylist_add_tail(MyList *tl, void *cum){
    MyNode *tmp=NULL;

    for(mo_list_iter iter=mo_mylist_start(tl); iter.var!=NULL;mo_mylist_iter_next(&iter)){
        tmp=iter.var;
    }
    
    MyNode *tmp2=mo_node_new(tl, cum);
    if(tmp==NULL){
        tl->head->next=tmp2;
        return;
    }
    tmp->next=tmp2;
}

void mo_mylist_delete(MyList *tl){
    MyNode *tmp=NULL;
    for (mo_list_iter iter=mo_mylist_start(tl); iter.var!=NULL; mo_mylist_iter_next(&iter)) {
        if(tmp!=NULL){
            free(tmp->value);
        }
        free(tmp);
        tmp=iter.var;
    }
}

MyList *mo_mylist_new_fromlist(MyList *tl){
    MyList *tmp=mo_mylist_new(tl->size);
    for (mo_list_iter iter=mo_mylist_start(tl); iter.var!=NULL; mo_mylist_iter_next(&iter)) {
        mo_mylist_add_tail(tmp, iter.var->value);
    }
    return tmp;
}